/*
 * display.c
 *
 *  Created on: Nov 27, 2019
 *      Author: Standa
 */

#include "display.h"
#include "syndet.h"
#include "ssd1306.h"
#include "utility.h"
#include "qfplib.h"
#include "bbb.h"


//INIT SCREEN INFO --- 18 char per line max
#define DEVSTRING	"   Handy LCR 001"
#define NAMESTRING	"By Stanislav Subrt"
#define REVSTR		"HWAA, FWAA, 191231"


#define TMPSIZE	18
char Tmp[TMPSIZE];
char Line[TMPSIZE];
#define ENGFLOATLEN	5



/*
 * Draws frame around specified area (optionally filled with black color)
 */
void disp_DrawFrame(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t isFilled){

	for(uint8_t i=y1; i<=y2; i++){
		if(isFilled) for(uint8_t j=x1; j<=x2; j++) ssd1306_DrawPixel(j, i, Black);
		ssd1306_DrawPixel(x1, i, White);
		ssd1306_DrawPixel(x2, i, White);
	}

	for(uint8_t i=x1; i<=x2; i++){
		ssd1306_DrawPixel(i, y1, White);
		ssd1306_DrawPixel(i, y2, White);
	}
}


/*
 * Draws pop-up window with specified frequency in the center of the screen
 */
void disp_DrawFrequencyPopup(float freq){

	  //SECOND LINE
	uint8_t Cnt = 0;
	Line[Cnt++] = 'F';
	Line[Cnt++] = 'r';
	Line[Cnt++] = 'e';
	Line[Cnt++] = 'q';
	Line[Cnt++] = '=';
	Cnt += ut_ConvFloatToEngStr(freq, Line+Cnt, Tmp, ENGFLOATLEN, 3);
	Line[Cnt++] = 0;

	disp_DrawFrame(26, 8, 100, 22, 1);
	ssd1306_SetCursor(28, 10);
	ssd1306_WriteString(Line, Font_7x10, White);
	ssd1306_UpdateScreen();
}


/*
 * Draws loading screen with battery voltage and core temperature
 */
void disp_DrawInitScreen(float temp, float vbat){
	ssd1306_Fill(Black);
	ssd1306_SetCursor(0, 0);
	ssd1306_WriteString(DEVSTRING, Font_7x10, White);

	ssd1306_SetCursor(0, 10);
	ssd1306_WriteString(NAMESTRING, Font_7x10, White);

	ssd1306_SetCursor(0, 20);
	ssd1306_WriteString(REVSTR, Font_7x10, White);
	ssd1306_UpdateScreen();
}


/*
 * Draws loading screen with battery voltage and core temperature
 */
void disp_DrawProggressScreen(float temp, float vbat){
	ssd1306_Fill(Black);
	//FIRST LINE
	uint8_t Cnt = 0;
	Line[Cnt++] = 'V';
	Line[Cnt++] = 'B';
	Line[Cnt++] = 'A';
	Line[Cnt++] = 'T';
	Line[Cnt++] = '=';
	Cnt += ut_ConvFloatToEngStr(vbat, Line+Cnt, Tmp, ENGFLOATLEN, 3);
	Line[Cnt++] = 0;

	ssd1306_SetCursor(0, 0);
	ssd1306_WriteString(Line, Font_7x10, White);


	//SECOND LINE
	Cnt = 0;
	Line[Cnt++] = 'T';
	Line[Cnt++] = 'E';
	Line[Cnt++] = 'M';
	Line[Cnt++] = 'P';
	Line[Cnt++] = '=';
	Cnt += ut_ConvFloatToEngStr(temp, Line+Cnt, Tmp, ENGFLOATLEN, 3);
	Line[Cnt++] = 0;

	ssd1306_SetCursor(0, 10);
	ssd1306_WriteString(Line, Font_7x10, White);
	ssd1306_UpdateScreen();
}


/*
 * Draws screen with measurement results
 * Either averages or stdevs might be printed (are typically printed)
 * average reactance is provided to determine whether DUT is capacitive or inductive
 */
void disp_DrawResultsScreen(sd_Results *res, uint8_t isStdevRequested){

	if(res==0){
		  disp_DrawInitScreen(bbb_GetTemp(), bbb_GetVbat());
		return;
	}

	ssd1306_Fill(Black);

	//FIRST LINE
	uint8_t Cnt = 0;
	Line[Cnt++] = 'Z';
	Line[Cnt++] = '=';
	Cnt += ut_ConvFloatToEngStr( (isStdevRequested) ? (res->Z->Stdev) : (res->Z->Mean), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	Line[Cnt++] = ' ';
	Line[Cnt++] = '@';
	Line[Cnt++] = ' ';
	if(isStdevRequested){
	  Line[Cnt++] = 'F';
	  Line[Cnt++] = 'M';
	  Line[Cnt++] = 'I';
	  Line[Cnt++] = '=';
	  Cnt += ut_ConvFloatToEngStr(res->FMI, Line+Cnt, Tmp, ENGFLOATLEN, 3);
	  Line[Cnt++] = 0;
	}
	else{
	  Line[Cnt++] = 'F';
	  Line[Cnt++] = '=';
	  Cnt += ut_ConvFloatToEngStr(sd_GetMeasFreq(), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	  Line[Cnt++] = 0;
	}

	ssd1306_SetCursor(0, 0);
	ssd1306_WriteString(Line, Font_7x10, White);

	//SECOND LINE
	Cnt = 0;
	Line[Cnt++] = 'R';
	Line[Cnt++] = '=';
	Cnt += ut_ConvFloatToEngStr((isStdevRequested) ? (res->R->Stdev) : (res->R->Mean), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	Line[Cnt++] = ' ';
	Line[Cnt++] = 'X';
	Line[Cnt++] = '=';
	Cnt += ut_ConvFloatToEngStr((isStdevRequested) ? (res->X->Stdev) : (res->X->Mean), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	Line[Cnt++] = ' ';
	Line[Cnt++] = 0;
	ssd1306_SetCursor(0, 11);
	ssd1306_WriteString(Line, Font_7x10, White);

	//THIRD LINE
	Cnt = 0;
	if(res->X->Mean >= 0){	//Inductive load, display L and Q
	  Line[Cnt++] = 'L';
	  Line[Cnt++] = '=';
	  Cnt += ut_ConvFloatToEngStr((isStdevRequested) ? (res->L->Stdev) : (res->L->Mean), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	  Line[Cnt++] = ' ';
	  Line[Cnt++] = 'Q';
	  Line[Cnt++] = '=';
	  Cnt += ut_ConvFloatToEngStr((isStdevRequested) ? (qfp_fdiv(1, res->D->Stdev)) : (qfp_fdiv(1, res->D->Mean)), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	  Line[Cnt++] = ' ';
	}
	else{			//Capacitive load, display C and D
	  Line[Cnt++] = 'C';
	  Line[Cnt++] = '=';
	  Cnt += ut_ConvFloatToEngStr((isStdevRequested) ? (res->C->Stdev): (res->C->Mean), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	  Line[Cnt++] = ' ';
	  Line[Cnt++] = 'D';
	  Line[Cnt++] = '=';
	  Cnt += ut_ConvFloatToEngStr((isStdevRequested) ? (res->D->Stdev) : (res->D->Mean), Line+Cnt, Tmp, ENGFLOATLEN, 3);
	  Line[Cnt++] = ' ';
	}
	Line[Cnt++] = 0;

	ssd1306_SetCursor(0, 21);
	ssd1306_WriteString(Line, Font_7x10, White);
	ssd1306_UpdateScreen();
}
